<?php
error_reporting(E_ERROR);

/**
 * 返回缩略图路径
 * @version 1.0.0 首次引入
 * @param string $filePath 必需;原图路径;空
 * @param string $suffix 可选;后缀名;thumb
 * @return string 缩略图访问地址
 */
function xfThumb($filePath='', $suffix='thumb')
{
    if($filePath){
        $file = pathinfo($filePath);
        return $file['dirname'].'/'.$file['filename'].'_'.$suffix.'.'.$file['extension'];
    }
    return false;
}

/**
 * 过滤连续空白
 * @version 1.0.0 首次引入
 * @param string $str 必需;待过滤的字符串;空
 * @return string 处理后的字符串
 */
function xfTrim($str=''){
    $str = str_replace("　",' ',str_replace("&nbsp;",' ',trim($str)));
    $str = preg_replace('#\s+#', ' ', $str);
    return $str;
}

/**
 * 编辑器解析
 * @version 1.0.0 首次引入
 * @param string $text 必需;需解析的markdown代码;空
 * @param number $line 可选;只返回固定几行;0
 * @return int
 */
function xfMarkdown($text='',$line=0){
    if($line > 0){
        //$text = str_replace(["\r","\n"], chr(13), $text);
        $textArr = explode(chr(13), $text);
        if(count($textArr) > $line){
            $textArr = array_slice($textArr, 0, $line);
            $text = implode(chr(13),$textArr);
        }
    }
    $parser = new \editor\Markdown();
    $parser->_html = true;
    return $parser->makeHtml($text);
}

/**
 * 匹配数字
 * @version 1.0.0 首次引入
 * @param string $string 文本
 * @return int
 */
function xfNumber($string='')
{
    return xfPregMatch('([0-9]+)',$string);
}

/**
 * 积分描述
 * @version 1.0.0 首次引入
 * @param string $value 状态值
 * @return array
 */
function xfScoreName($name='register'){
    $array= model('common/Attr','loglic')->scoreName();
    if(in_array($name,array_keys($array))){
        return $array[$name];
    }
    return '未知';
}

/**
 * 状态描述
 * @version 1.0.0 首次引入
 * @param string $value 状态值
 * @return array
 */
function xfStatus($value='normal'){
    $arrayStatus = model('common/Attr','loglic')->status();
    if(in_array($value,array_keys($arrayStatus))){
        return $arrayStatus[$value];
    }
    return '未知';
}

/**
 * 订单支付状态
 * @version 1.0.0 首次引入
 * @param string $ptah 模型路径
 * @param string $args 查询参数
 * @return array
 */
function xfStatusPay($value=1){
    if($value==2){
        return '已付款';
    }
    return '未支付';
}

/**
 * 数组保存到文件
 * @version 1.0.0 首次引入
 * @param string $filename 完整文件路径名
 * @param string $dataArray 数组
 * @return bool
 */
function xfArrayWrite($fileName='', $dataArray=''){
    $file = new \files\File();
    if(!$file->f_has($fileName)){
        return 0;
    }
    if(!$file->is_write($fileName)){
        return 0;
    }
    return $file->write_array($fileName, $dataArray);
}

/**
 * 给一个数组参数或者url字符串（args）绑定默认值
 * @version 1.0.0 首次引入
 * @param array $args 必需;数组参数列表
 * @param array $defaults 可选;数组默认值;默认：空
 * @return array 合并后的数组
 */
function xfArrayArgs($args=[], $defaults=''){
	if ( is_array( $args ) ){
		$r =& $args;
    }else{
		parse_str( $args, $r );
    }
	if ( is_array( $defaults ) ){
		return array_merge( $defaults, $r );
    }
	return $r;
}

/**
 * 过滤数组中不需要的字段
 * @version 1.0.0 首次引入
 * @param array $array 必需;待过滤的数组
 * @param array $fileds 必需;需保留的字段
 * @param string $prefix 可选;KEY前缀
 * @param string $suffix 可选;KEY后缀
 * @return mixed 过滤后的数组(array|value)
 */
function xfArrayFilter($array=[], $fileds=[], $prefix='', $suffix=''){
    $filter = [];
    foreach($array as $key=>$value){
        if(in_array($key, $fileds)){
            $filter[$prefix.$key.$suffix] = $value;
        }
    }
    return $filter;
}

/**
 * 返回数组的指定KEY
 * @version 1.0.0 首次引入
 * @param array $array 必需;需验证的数据集;默认：空
 * @return array
 */
function xfArrayKey($array=[],$key='key'){
    return $array[$key];
}

/**
 * 过滤数组中的空值
 * @version 1.0.0 首次引入
 * @param array $array 必需;需过滤的数组;默认：空
 * @return array
 */
function xfArrayTrim($array=[]){
    return array_filter($array, function($value){
        return !empty($value);
    });
}

/**
 * 判断是否为（普通/多维）数组
 * @version 1.0.0 首次引入
 * @param array $array 必需;待验证的数组;默认：空
 * @param bool $mode 可选;多维数组模式;默认：false
 * @return bool true|false
 */
function xfIsArray($array=[], $mode=false){
    //验证普通数组模式
    if($mode == false){
        return is_array($array);
    }
    //验证多维数组模式
    if(count($array, 1) == 1){
        return false;
    }
    //计算一维与多维是否相同，统计相同则是一维，不相同则是多维
    if (count($array) == count($array, 1)) {
        return false;
    } else {
        return true;
    }
}

/**
 * 返回数据集列表指定列的结果
 * @version 1.0.0 首次引入
 * @param array $datas 数据集列表
 * @param string $valueField 键值
 * @param string $keyField 键名
 * @return array
 */
function xfResultColumn($datas=[],$valueField='type_name',$keyField='type_id'){
    return array_column($datas, $valueField, $keyField);
}

/**
 * 返回数据集列表按间隔符分开
 * @version 1.0.0 首次引入
 * @param array $datas 数据集列表
 * @param string $valueField 键值
 * @param string $keyField 键名
 * @return array
 */
function xfResultImplode($datas=[],$valueField='type_name',$keyField='type_id'){
    return implode(array_values(xfResultColumn($datas, $valueField, $keyField)),',');
}

/**
 * 返回数据集列表第一个数据的指定值
 * @version 1.0.0 首次引入
 * @param array $datas 数据集列表
 * @param string $field 键名
 * @return array
 */
function xfResultCurrent($datas=[],$field='type_name'){
    $array = current($datas);
    return $array[$field];
}

/**
 * 将数据集转化为数组
 * @version 1.0.0 首次引入
 * @param mixed $data 必需;需验请的数据集;默认：空
 * @return mixed array|null
 */
function xfResult($data=[]){
    if(is_null($data)){
        return null;
    }
    if(is_object($data)){
        return $data->toArray();
    }
    return $data;
}

/**
 * OnOff快捷输出
 * @version 1.0.0 首次引入
 * @param string $value 必需;待验证的字符串
 * @return string on|off
 */
function xfSwitch($value=''){
    if( xfBool($value) ){
        return 'on';
    }
    return 'off';
}

/**
 * BOOL快捷输出
 * @version 1.0.0 首次引入
 * @param string $value 必需;待验证的字符串
 * @param bool $default 可选;验证规则;默认：true
 * @return string true|false
 */
function xfBool($value='', $default=true){
    $array = ['1', 'true', 'on', 'yes'];
    if(in_array(strtolower($value), $array)){
        return $default;
    }
    return false;
}

/**
 * 字符串空值快捷输出
 * @version 1.0.0 首次引入
 * @param string $value 必需;待验证的字符串
 * @param mixed $default 必需;默认值;默认：空
 * @return string 验证后的字符串
 */
function xfEmpty($value='', $default=''){
    return !empty($value) ? $value : $default;
}

/**
 * 字符串相同后输出高亮类型
 * @version 1.0.0 首次引入
 * @param string $value1 必需;待验证的字符串;默认：空
 * @param string $value2 必需;待比较的字符串;默认：空
 * @param string $default 可选;高亮属性值;默认：active
 * @return string 高亮属性值
 */
function xfActive($value1='', $value2='', $active='active'){
    if($value1 == $value2 && $value1){
        return $active;
    }
    return '';
}

/**
 * 转算SQL查询的总记录数
 * @version 1.0.0 首次引入
 * @param string $value 必需;待验证的值;默认：0
 * @return string 高亮属性值
 */
function xfTotal($value=0){
    if($value > 0){
        return $value;
    }
    return false;
}

/**
 * 字符串作比较是否相同后输出不同值
 * @version 1.0.0 首次引入
 * @param string $value 必需;待验证的字符串
 * @param string $default 必需;待比较的字符串;默认：空
 * @param string $stringTrue 必需;比较结果为真时输出的字符;默认：active
 * @param string $empty 必需;比较结果为假时输出的字符;默认：空
 * @return string 验证后的字符串
 */
function xfDefault($value='', $default='', $stringTrue='active', $stringFalse=''){
    if(is_array($default)){
        if(in_array($value,$default)){
            return $stringTrue;
        }
    }else{
        if($value == $default){
            return $stringTrue;
        }
    }
    return $stringFalse;
}

/**
 * 字符串截取
 * @version 1.0.0 首次引入
 * @param string $str 必需;待截取的字符串
 * @param int $start 必需;起始位置;默认：0
 * @param int $length 必需;截取长度;默认：空
 * @param bool $suffix 可选;超出长度是否以...显示;默认：true
 * @param string $charset 可选;字符编码;默认：utf-8
 * @return string 截取后的字符串
 */
function xfSubstr($str='', $start=0, $length, $suffix=true, $charset="UTF-8"){
    $str = trim($str);
    if( function_exists('mb_strimwidth') ){
        if($suffix){
            return mb_strimwidth($str, $start, $length*2, '...', $charset);
        }
        return mb_strimwidth($str, $start, $length*2, '', $charset);
    }
    return @substr($str, $start, $length);
}

/**
* 下划线转驼峰
* @version 1.0.0 首次引入
* @param string $uncamelized_words 下划线样式的字符串
* @param string $separator 分隔符/默认'_'
* @return string 驼峰样式的字符串
* step1.原字符串转小写,原字符串中的分隔符用空格替换,在字符串开头加上分隔符
* step2.将字符串中每个单词的首字母转换为大写,再去空格,去字符串首部附加的分隔符.
*/
function xfCamelize($uncamelized_words='', $separator='_'){
    $uncamelized_words = $separator. str_replace($separator, " ", strtolower($uncamelized_words));
    return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator );
}

/**
 * 字符串转拼音(1=首字母去除非汉字，2＝首字母包含非汉字，3=无声调，4＝有声调)
 * @version 1.0.0 首次引入
 * @param string $string 必需;待转化的字符;默认：空
 * @param int $type 必需;转换类型;默认：1
 * @param string $delimiter 可选;分隔符;默认：空
 * @param bool $isFirst 可选;是否只返回一个字母;默认：false
 * @return string 转换后的拼音
 */
function xfSlug($words='', $type=1, $delimiter='-', $isFirst=false){
    $pinyin = new \string\ChinesePinyin();
    if($type==1){
        //转成汉语拼音首字母,包含非汉字内容
        $result = $pinyin->TransformUcwords($words,$delimiter,true);
    }else if($type==2){
        //转成汉语拼音首字母,只包括汉字,不包含拼音
        $result = $pinyin->TransformUcwordsOnlyChar($words,$delimiter);
    }else if($type==3){
        //无声调的汉语拼音
        $result = $pinyin->TransformWithoutTone($words,$delimiter);
    }else if($type==4){
        //带声调的汉语拼音
        $result = $pinyin->TransformWithTone($words,$delimiter);
    }
    //是否只返回首字母
    if($isFirst){
        return mb_substr($result, 0, 1,'UTF-8');
    }
    //返回结果
    return $result;
}

/**
 * 隐藏完整手机号
 * @version 1.0.0 首次引入
 * @param string $mobile 必需;手机号
 * @return string 过滤后的手机号
 */
function xfMobile($mobile=''){
    return substr_replace($mobile, '****', 3, 4);
}

/**
 * 获取分类页链接
 * @version 1.0.0 首次引入
 * @param array $info 必需;[id,name,slug]；默认：空
 * @param mixed $pageNumber 可选;int|[PAGE];默认:空
 * @return string 生成的内部网址链接
 */
function xfUrlType($info=[], $page=1, $path='blog/type/index')
{
    $args = [];
    $routes = array_column(config('route.'),0,1);
    //必要参数
    if( preg_match('/:slug|<slug/i',$routes[$path]) ){
        $args['slug'] = $info['type_slug'];
    }else{
        $args['id'] = $info['type_id'];
    }
    //分页参数
    if($page > 1){
        $args['page'] = $page;
    }else{
        if(preg_match('/</i',$routes[$path])){
            $args['page'] = 1;
        }
    }
    unset($info);
    return xfUrl($path, $args);
}

/**
 * 获取标签详情页链接
 * @version 1.0.0 首次引入
 * @param array $info 必需;[id,name,slug]；默认：空
 * @param mixed $pageNumber 可选;int|[PAGE];默认:空
 * @return string 生成的内部网址链接
 */
function xfUrlTag($info=[], $page=1, $path='blog/tag/index')
{
    $args = [];
    $routes = array_column(config('route.'),0,1);
    //必要参数
    if( preg_match('/:slug|<slug/i',$routes[$path]) ){
        $args['slug'] = $info['tag_slug'];
    }else{
        $args['id'] = $info['tag_id'];
    }
    //分页参数
    if($page > 1){
        $args['page'] = $page;
    }else{
        if(preg_match('/</i',$routes[$path])){
            $args['page'] = 1;
        }
    }
    unset($info);
    return xfUrl($path, $args);
}

/**
 * 获取文章详情页链接
 * @version 1.0.0 首次引入
 * @param array $info 必需;[id,name,slug]；默认：空
 * @param mixed $pageNumber 可选;int|[PAGE];默认:空
 * @return string 生成的内部网址链接
 */
function xfUrlDetail($info=[], $path='blog/detail/index')
{
    $args = [];
    $routes = array_column(config('route.'),0,1);
    //必要参数
    if( preg_match('/:slug|<slug/i',$routes[$path]) ){
        $args['slug'] = $info['detail_slug'];
    }else{
        $args['id'] = $info['detail_id'];
    }
    unset($info);
    return xfUrl($path, $args);
}

/**
 * 生成后台筛选链接
 * @version 1.0.0 首次引入
 * @param string $url 必需;调用地址
 * @param array $vars 必需;合并参数;默认：空
 * @param array $query 必需;初始参数;默认：空
 * @return string 筛选链接
 */
function xfUrlFilter($url='', $vars=[], $query=[]){
    if($query&&$vars){
        return xfUrl($url,array_merge($query,$vars));
    }
    if($query){
        return xfUrl($url,$query);
    }
    return xfUrl($url,$vars);
}

/**
 * 生成分页查询时的PATH参数
 * @version 1.0.0 首次引入
 * @param string $url 必需;模块地址;默认：空
 * @param array $query 必需;分页参数;默认：空
 * @return string 用于分页参数的PATH
 */
function xfUrlPath($url='',$query=[]){
    $query['page'] = '[PAGE]';
    return xfUrl($url,$query);
}

/**
 * 内部模块链接与外部网址链接格式化
 * @version 1.8.0 首次引入
 * @param string $url 必需;待验证的网址;默认：空
 * @return string 转换后的链接
 */
function xfUrlParse($url=''){
    if(!$url){
        return 'javascript:;';
    }
    //分解网址参数
    $array = parse_url($url);
    if($array['scheme']){
        return $url;
    }
    //内部链接
    return xfUrl($array['path'], $array['query']);
}

/**
 * 获取跳转URL
 * @version 1.0.0 首次引入
 * @return string 记忆的URL
 */
function xfUrlRedirect(){
    if($restore = input('session.redirect_url')){
        session('redirect_url', null);
        return $restore;
    }else{
        return 'user/index/index';
    }
}

/**
 * 生成站内链接
 * @version 1.0.0 首次引入
 * @param string $url 必需;调用地址
 * @param string|array $vars 可选;调用参数，支持字符串和数组;默认：空
 * @return string 站内链接
 */
function xfUrl($url='', $vars=''){
    return str_replace('%5BPAGE%5D', '[PAGE]', url($url, $vars, config('site.suffix'), false));
}

/**
 * 读取远程数据
 * @version 1.0.0 首次引入
 * @param string $useragent 必需;模拟用户HEAD头,可选值有（auto|windows|linux|ios|iphone）;默认：auto
 * @param int $timeout 必需;超时时间;默认：10
 * @param string $url 必需;待抓取的远程地址;默认：空
 * @param array $post_data 可选;post请求时发送的数据，留空则为get请求;默认：空
 * @param string $referer 可选;模拟来湃URL地址;默认：空
 * @param array $headers 可选;自定义请求头;默认：空
 * @param string $cookie 可选;模拟cookie信息;默认：空
 * @param string $proxy 可选;代理请求信息;默认：空
 * @return string 返回读取远程网页的内容
 */
function xfCurl($useragent='auto', $timeout=10, $url='', $post_data='', $referer='', $headers=[], $cookie='', $proxy=''){
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_URL, $url);
    curl_setopt ($ch, CURLOPT_HEADER, 0);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt ($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);//301 302
    curl_setopt ($ch, CURLOPT_ENCODING, "");//乱码是因为返回的数据被压缩过了，在curl中加上一项参数即可
    //useragent
    if($useragent == 'windows'){
        curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50');
    }elseif($useragent == 'linux'){
        curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:20.0) Gecko/20100101 Firefox/20.0');
    }elseif($useragent == 'ios'){
        curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50');
    }elseif($useragent == 'iphone'){
        curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X; zh-CN) AppleWebKit/537.51.1 (KHTML, like Gecko) Mobile/14F89 UCBrowser/10.9.17.807 Mobile');
    }elseif($useragent == 'android'){
        curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Linux; U; Android 7.1.1; zh-cn; OPPO R11st Build/NMF26X) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.134 Mobile Safari/537.36 OppoBrowser/4.6.5.3');
    }    
    //是否post
    if(is_array($post_data)){
        curl_setopt($ch, CURLOPT_POST, 1);// post数据
        if($headers[0] == 'Content-Type: application/json'){
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));    // post的变量
        }else{
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);    // post的变量
        }
    }
    //是否伪造来路
    if($referer){
        curl_setopt ($ch, CURLOPT_REFERER, $referer);
    }
    //是否headers
    if(is_array($headers)){
        curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
    }    
    //是否cookie
    if($cookie){
        curl_setopt ($ch, CURLOPT_COOKIE, $cookie);
    }
    //IP代理
    if($proxy){
        curl_setopt ($ch, CURLOPT_PROXY, $proxy);
    }    
    //https自动处理
    $http = parse_url($url);
    if($http['scheme'] == 'https'){
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    }
    $content = curl_exec($ch);
    curl_close($ch);
    //返回结果
    if($content){
        return $content;
    }
    return false;
}

//快速匹配正则
function xfPregMatch($rule='', $html=''){
    $arr = explode('$$$',$rule);
    if(count($arr) == 2){
        preg_match('/'.$arr[1].'/', $html, $data);
        return $data[$arr[0]].'';
    }else{
        preg_match('/'.$rule.'/', $html, $data);
        return $data[1].'';
    }
}

//表单生成
function xfFormCreate($args=[]){
    //表单字段属性
    foreach($args['items'] as $field=>$attr){
        if($attr['type']){
            $args['items'][$field] = xfFormItem($field, $attr);
        }else{
            unset($args['items'][$field]);
        }
    }
    //初始值
    $form = array();
    $form['name']           = 'form';//表单名称用于钩子判断
    $form['action']         = '#';//表单提交地址
    $form['method']         = 'post';//表单提交方法
    $form['target']         = '_self';//窗口打开方式
    $form['class']          = 'w-100';//表单样式表
    $form['disabled']       = false;//是否禁用
    $form['ajax']           = true;//AJAX操作
    $form['call_back']      = '';//AJAX回调
    $form['submit']         = '提交';//提交按钮名称
    $form['reset']          = '';//重置按钮名称
    $form['close']          = '';//关闭按钮名称
    $form['class_row']      = 'w-100';//堆叠表单w-100,内联表单row
    $form['class_button']   = 'text-center';//按钮组
    $form['class_submit']   = 'btn btn-dark';//提交按钮CLASS
    $form['class_reset']    = 'btn btn-secondary';//重置按钮CLASS
    $form['class_close']    = 'btn btn-danger';//关闭按钮CLASS
    $form['items']          = [];//表单元素列表
    //参数合并
    $form = array_merge($form, $args);
    //释放内存
    unset($args);
    //模板渲染
    return view('./widget/form/index.tpl',$form)->getContent();
}

//多个表单组件属性
function xfFormItems($fields=[]){
    foreach($fields as $field=>$attr){
        if($attr['type']){
            $fields[$field] = xfFormItem($field, $attr);
        }else{
            unset($fields[$field]);
        }
    }
    return $fields;
}

//单个表单组件属性
function xfFormItem($field='', $attr=[], $isParse=false){
    //默认属性
    $default = [
        'type'                => 'text',
        'name'                => $field,
        'id'                  => $field,
        'value'               => '',
        'title'               => '',
        'placeholder'         => '',
        'tips'                => '',
        'autofocus'           => '',
        'readonly'            => false,
        'disabled'            => false,
        'required'            => false,
        'template'            => xfEmpty($attr['template'],'./widget/form/'.$attr['type'].'.tpl'),
        'class_row'           => 'w-100 mb-3',//row mb-3
        'class_label'         => 'form-label',//col-2 col-form-label
        'class_col'           => '',//col-10
        'class_input'         => 'form-control form-control-sm',
        'class_tips'          => '',
    ];
    //表单类型特有属性
    if( in_array($attr['type'],['textarea','editor','json']) ){
        $default['rows']         = 10;
    }elseif( in_array($attr['type'],['custom','select']) ){
        $default['option']      = [];
        $default['class_input'] = 'form-select form-select-sm';
        if($attr['multiple']){
            $default['name']    = $field.'[]';
            $default['id']      = $field.'[]';
        }
    }elseif( in_array($attr['type'],['checkbox']) ){
        $default['option']      = [];
        $default['class_row']   = 'form-check form-check-inline';
    }elseif( in_array($attr['type'],['switch','radio']) ){
        $default['option']      = [];
        $default['class_row']   = 'form-check form-check-inline';
    }elseif( in_array($attr['type'],['list-check']) ){
        $default['option']      = [];
        $default['class_input'] = 'form-select form-select-sm form-control';
    }elseif( in_array($attr['type'],['image']) ){
        $default['class_input'] = 'input-group-sm';
    }else{
        $default['maxlength']    = '250';
        $default['autocomplete'] = 'off';
    }
    //返回结果
    return xfArrayArgs($attr, $default);
}

//渲染模板
function xfView($args=[]){
    $path = $args['template'] ? $args['template'] : './widget/form/default.tpl';
    return view($path,$args)->getContent();
}

/**
 * 获取指定分类的所有子集(递归法)
 * @param array $categorys 数组列表
 * @param int $catId 主键ID值
 * @param int $level 层级记录数
 * @param int $pk 主键名称
 * @param int $pid 父级名称
 * @return array 数组列表;
 */
function xfChildrens($categorys=[], $catId=0, $level=1, $pk='type_id', $pid='type_parent'){
    $subs = array();
    foreach($categorys as $item){
        if($item[$pid] == $catId){
            $item['level'] = $level;
            $subs[] = $item;
            $subs = array_merge($subs, xfChilds($categorys, $item[$pk], $level+1, $pk, $pid) );
        }
    }
    return $subs;
}
/**
 * 获取某一个子类的所有父级(递归法)
 * @param array $categorys 数组列表
 * @param int $parentId 父级ID值
 * @param int $pk 主键名称
 * @param int $pid 父级名称
 * @return mixed null|array;
 */
function xfParents($categorys=[], $parentId, $pk='type_id', $pid='type_parent'){
    $tree = array();
    foreach($categorys as $item){
        if($item[$pk] == $parentId){
            $tree[] = $item;
            $tree = array_merge($tree, xfParents($categorys, $item[$pid], $pk, $pid) );
        }
    }
    return $tree;
}